#!/usr/bin/env python2

import sys;
import binascii;

from GoodFET import GoodFET;
from intelhex import IntelHex16bit;

if(len(sys.argv)==1):
    print "Usage: %s verb [objects]\n" % sys.argv[0];
    print "%s test" % sys.argv[0];
    print "%s dump $foo.hex [0x$start 0x$stop]" % sys.argv[0];
    print "%s ivt" % sys.argv[0];
    print "%s peek [0x$start 0x$stop]" % sys.argv[0];
    print "%s verify $foo.hex [0x$start 0x$stop]" % sys.argv[0];
    print "%s ramfill" % sys.argv[0];
    print "%s ramdepth" % sys.argv[0];
    print "%s info" % sys.argv[0];
    print "%s call 0x$start" % sys.argv[0];
    print "%s exec '0x35 0x00 0x..'" % sys.argv[0];
    print "%s listapps [full]" % sys.argv[0]
    print "%s testleds" % sys.argv[0]
    sys.exit();

#Initialize FET and set baud rate
client=GoodFET();
client.serInit()
#client.verbose=1;

if(sys.argv[1]=="on"):
    client.dir(0xFF);
    client.out(0xFF);
if(sys.argv[1]=="off"):
    client.out(0x00);

if(sys.argv[1]=="glitchtest"):
    client.writecmd(client.GLITCHAPP,0x20,0,None);

if(sys.argv[1]=="call"):
    adr=int(sys.argv[2],16);
    print "Calling %04x" % adr;
    client.call(adr);
if(sys.argv[1]=="exec"):
    code="";
    for foo in sys.argv[2].split(" "):
        code+=chr(int(foo,16));
    code+="\x30\x41";
    client.execute(code);
    
if(sys.argv[1]=="info"):
    client.monitor_info()
if(sys.argv[1]=="infotest"):
    for foo in range(0,100):
        client.monitor_info()

if(sys.argv[1]=="clocktest"):
    print "GoodFET with %s MCU" % client.infostring();
    clocking=client.monitorgetclock();
    print "Clocked at 0x%04x" % clocking;
    for foo in range(1,50):
        client.monitorsetclock(clocking+foo);
        print "+0x%04x: %s" % (foo,client.infostring());
        client.monitorsetclock(clocking-foo);
        print "-0x%04x: %s" % (foo,client.infostring());
        
if(sys.argv[1]=="listapps" or sys.argv[1]=="apps"):
    full = (len(sys.argv) > 2) and (sys.argv[2]=="full")
    client.monitor_list_apps(full);
    
if(sys.argv[1]=="ramfill"):
    client.monitor_ram_pattern();
if(sys.argv[1]=="ramdepth"):
    print "0x%04x RAM bytes free." % client.monitor_ram_depth();
if(sys.argv[1]=="test"):
    client.monitortest();
if(sys.argv[1]=="findbaud"):
    client.findbaud();
if(sys.argv[1]=="dump"):
    f = sys.argv[2];
    start=0x0200;
    stop=0xFFFF;
    if(len(sys.argv)>3):
        start=int(sys.argv[3],16);
    if(len(sys.argv)>4):
        stop=int(sys.argv[4],16);
    
    print "Dumping from %04x to %04x as %s." % (start,stop,f);
    h = IntelHex16bit(None);
    i=start;
    while i<stop:
        h[i>>1]=client.peek16(i);
        if(i%0x100==0):
            print "Dumped %04x."%i;
        i+=2;
    h.write_hex_file(f);
if(sys.argv[1]=="erase"):
    client.masserase();
if(sys.argv[1]=="ivt"):
    client.dumpmem(0xFFE0,0xFFFF);

if(sys.argv[1]=="peek"):
    start=0xFFE0;
    stop=0xFFFF;
    if(len(sys.argv)>2):
        start=int(sys.argv[2],16);
        stop=start+1
    if(len(sys.argv)>3):
        stop=int(sys.argv[3],16);
    
    client.dumpmem(start,stop);
if(sys.argv[1]=="verify"):
    f=sys.argv[2];
    start=0;
    stop=0xFFFF;
    if(len(sys.argv)>3):
        start=int(sys.argv[3],16);
    if(len(sys.argv)>4):
        stop=int(sys.argv[4],16);
    
    h = IntelHex16bit(f);
    for i in h._buf.keys():
        if(i>=start and i<stop and i&1==0):
            peek=client.peek(i)
            if(h[i>>1]!=peek):
                print "ERROR at %04x, found %04x not %04x"%(i,peek,h[i>>1]);
            if(i%0x100==0):
                print "%04x" % i;

if(sys.argv[1]=="testleds"):
    client.testleds();
